package com.xlh.service.course.impl;

import com.google.common.collect.Lists;
import com.xlh.dao.course.StepChapterMapper;
import com.xlh.dao.course.StepMapper;
import com.xlh.dao.course.ext.StepChapterMapperExt;
import com.xlh.dto.course.StepDTO;
import com.xlh.enums.ResourceRelationTypeEnum;
import com.xlh.exception.common.BadRequestException;
import com.xlh.exception.common.NotFoundException;
import com.xlh.listener.AsyncTask;
import com.xlh.param.course.StepParam;
import com.xlh.pojo.course.Step;
import com.xlh.pojo.course.StepChapter;
import com.xlh.pojo.course.StepChapterExample;
import com.xlh.pojo.course.StepExample;
import com.xlh.service.course.ChapterService;
import com.xlh.service.course.StepService;
import com.xlh.util.BeanUtil;
import com.xlh.virtualization.service.ExperimentJudgeService;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * 步骤
 * <p>
 * Created by lx on 2020/6/12.
 */
@Service
public class StepServiceImpl implements StepService {

    @Autowired
    private StepMapper stepMapper;

    @Autowired
    private StepChapterMapper stepChapterMapper;

    @Autowired
    private StepChapterMapperExt stepChapterMapperExt;

    @Autowired
    private ChapterService chapterService;

    @Autowired
    private AsyncTask asyncTask;

    @Autowired
    private ExperimentJudgeService experimentJudgeService;

    @Override
    public List<StepDTO> listStep(Long chapterId) {
        return stepChapterMapperExt.listStep(chapterId);
    }

    @Override
    public List<StepChapter> listStepChapter(List<Long> chapterIds) {
        return queryStepChapterInfo(chapterIds);
    }

    @Override
    public void createStep(Long chapterId, StepParam param) {

        // 查询stepChapter的序号
        List<StepChapter> stepChapters = queryStepChapter(chapterId, null);

        Step step = BeanUtil.transform(Step.class, param);
        stepMapper.insertSelective(step);

        StepChapter stepChapter = new StepChapter();
        stepChapter.setChapterId(chapterId);
        stepChapter.setStepId(step.getId());
        stepChapter.setOrderNumber(stepChapters.stream()
                .map(StepChapter::getOrderNumber).reduce(Integer::max).orElse(0) + 1);
        stepChapterMapper.insertSelective(stepChapter);

    }

    @Override
    public void updateStepInfo(Long chapterId, Long id, StepParam param) {
        // 检查参数是否正确
        List<StepChapter> stepChapters = queryStepChapter(chapterId, id);
        if (CollectionUtils.isEmpty(stepChapters)) throw new BadRequestException();

        Step step = stepMapper.selectByPrimaryKey(id);
        if (step == null) throw new NotFoundException("");

        // 如果步骤名称相同 不需要做修改操作
        if (Objects.equals(step.getName(), param.getName())) return;

        // 获取是否被其他教师占用
        List<StepChapter> occupyStepChapters = queryOccupyStepChapter(chapterId, Lists.newArrayList(id));
        if (occupyStepChapters.stream()
                .filter(stepChapter -> Objects.equals(stepChapter.getStepId(), id)).count() > 0) {
            // 占用
            Step newStep = new Step();
            newStep.setName(param.getName());
            stepMapper.insertSelective(newStep);

            StepChapter stepChapter = new StepChapter();
            stepChapter.setId(stepChapters.get(0).getId());
            stepChapter.setStepId(newStep.getId());
            stepChapterMapper.updateByPrimaryKeySelective(stepChapter);
        } else {
            // 不占用
            Step step1 = new Step();
            step1.setId(id);
            step1.setName(param.getName());
            stepMapper.updateByPrimaryKeySelective(step1);
        }
    }

    @Override
    public List<String> deleteStep(Long chapterId, List<Long> ids, boolean deletedResource) {

        List<StepChapter> allStepChapter = queryStepChapter(chapterId, null);
        if (CollectionUtils.isEmpty(allStepChapter)) throw new NotFoundException("");
        if (CollectionUtils.isNotEmpty(ids)) {
            allStepChapter = allStepChapter.stream()
                    .filter(stepChapter -> ids.contains(stepChapter.getStepId())).collect(Collectors.toList());
        }
        if (CollectionUtils.isEmpty(allStepChapter)) throw new NotFoundException("");

        List<Long> deleteIds = allStepChapter.stream().map(StepChapter::getStepId).collect(Collectors.toList());
        List<Long> deleteStepChapterIds = allStepChapter.stream().map(StepChapter::getId).collect(Collectors.toList());

        // 删除步骤
        List<StepChapter> stepChapters = queryOccupyStepChapter(chapterId, deleteIds);
        List<Long> occupyStepIds = stepChapters.stream().map(StepChapter::getStepId).collect(Collectors.toList());
        List<StepChapter> deleteData = allStepChapter.stream()
                .filter(stepChapter -> !occupyStepIds.contains(stepChapter.getStepId()))
                .collect(Collectors.toList());
        List<Long> deleteStepIds = deleteData.stream().map(StepChapter::getStepId).collect(Collectors.toList());
        if (CollectionUtils.isNotEmpty(deleteStepIds)) {
            deleteStep(deleteStepIds);
        }

        // 删除步骤与章节的关联表
        StepChapterExample example = new StepChapterExample();
        example.createCriteria().andChapterIdEqualTo(chapterId).andStepIdIn(deleteIds);
        stepChapterMapper.deleteByExample(example);

        // 对现在的步骤进行排序
        List<StepChapter> currentData = queryStepChapter(chapterId, null);
        if (CollectionUtils.isNotEmpty(currentData)) {
            stepChapterMapperExt.updateOrderNum(currentData);
        }

        // 删除资源
        List<String> resourcePaths = chapterService.deleteAndGetResourceRelation(
                deleteStepChapterIds, null, null, ResourceRelationTypeEnum.STEP);
        if (deletedResource && CollectionUtils.isNotEmpty(resourcePaths)) {
            asyncTask.asyncDeleteStaticResources(resourcePaths);
        }

        experimentJudgeService.trueDelete(2, deleteStepIds);

        return resourcePaths;
    }

    @Override
    public void insertStepChapter(StepChapter stepChapter) {
        stepChapterMapper.insertSelective(stepChapter);
    }

    @Override
    public void insertBatchStep(List<Step> steps) {
        if (CollectionUtils.isEmpty(steps)) return;
        stepChapterMapperExt.insertBatchStep(steps);
    }

    @Override
    public void insertBatchStepChapter(List<StepChapter> stepChapters) {
        if (CollectionUtils.isEmpty(stepChapters)) return;
        stepChapterMapperExt.insertBatchStepChapter(stepChapters);
    }

    @Override
    public List<StepChapter> listStepChapterByIds(List<Long> ids) {
        StepChapterExample example = new StepChapterExample();
        example.createCriteria().andIdIn(ids);
        return stepChapterMapper.selectByExample(example);
    }

    private List<StepChapter> queryOccupyStepChapter(Long chapterId, List<Long> stepIds) {
        StepChapterExample example = new StepChapterExample();
        example.createCriteria().andChapterIdNotEqualTo(chapterId).andStepIdIn(stepIds);
        return stepChapterMapper.selectByExample(example);
    }

    private List<StepChapter> queryStepChapter(Long chapterId, Long stepId) {
        StepChapterExample example = new StepChapterExample();
        StepChapterExample.Criteria criteria = example.createCriteria();
        if (chapterId != null) {
            criteria.andChapterIdEqualTo(chapterId);
        }
        if (stepId != null) {
            criteria.andStepIdEqualTo(stepId);
        }
        return stepChapterMapper.selectByExample(example);
    }

    private List<StepChapter> queryStepChapter(List<Long> stepIds) {
        StepChapterExample example = new StepChapterExample();
        example.createCriteria().andStepIdIn(stepIds);
        return stepChapterMapper.selectByExample(example);
    }

    private List<StepChapter> queryStepChapterInfo(List<Long> chapterIds) {
        StepChapterExample example = new StepChapterExample();
        example.createCriteria().andChapterIdIn(chapterIds);
        return stepChapterMapper.selectByExample(example);
    }

    private void deleteStep(List<Long> ids) {
        StepExample example = new StepExample();
        example.createCriteria().andIdIn(ids);
        stepMapper.deleteByExample(example);
    }
}
